/*
 * Copyright 2007-2009 Perttu "celeron55" Ahola <celeron55@gmail.com>
 *
 * This file is part of jukumagic.
 *
 * jukumagic is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * jukumagic is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with jukumagic.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <iostream>

#include "common.h"
#include "boardpoint.h"
#include <cstdlib>

// BoardPoint

BoardPoint::BoardPoint()
{
	m_x = 0;
	m_y = 0;
	exists = false;
}

BoardPoint::BoardPoint(const BoardPoint &p)
{
	m_x = p.m_x;
	m_y = p.m_y;
	exists = p.exists;
}

BoardPoint::BoardPoint(int x, int y)
{
	m_x = x;
	m_y = y;
	exists = true;
}

BoardPoint::~BoardPoint()
{
}

void BoardPoint::operator=(BoardPoint p)
{
	m_x = p.m_x;
	m_y = p.m_y;
	exists = p.exists;
}

bool BoardPoint::operator==(BoardPoint p)
{
	return (m_x == p.m_x && m_y == p.m_y && exists && p.exists);
}

bool BoardPoint::operator!=(BoardPoint p)
{
	return (m_x != p.m_x || m_y != p.m_y || !exists || !p.exists);
}

void BoardPoint::operator+=(BoardPoint p)
{
	m_x += p.m_x;
}

void BoardPoint::operator-=(BoardPoint p)
{
	m_y += p.m_y;
}

BoardPoint BoardPoint::operator+(BoardPoint p)
{
	if(!exists && !p.exists) return BoardPoint();
	if(exists && !p.exists) return *this;
	//if(!exists && p.exists) return p;
	if(!exists && p.exists) return BoardPoint();
	return BoardPoint(m_x + p.m_x, m_y + p.m_y);
}

BoardPoint BoardPoint::operator-(BoardPoint p)
{
	if(!exists && !p.exists) return BoardPoint();
	if(exists && !p.exists) return *this;
	//if(!exists && p.exists) return BoardPoint(0,0) - p;
	if(!exists && p.exists) return BoardPoint();
	return BoardPoint(m_x - p.m_x, m_y - p.m_y);
}

int BoardPoint::DistanceSquared(BoardPoint p1, BoardPoint p2)
{
	if(!p1.exists || !p2.exists) return -1;
	int xd = abs(p1.m_x - p2.m_x);
	int yd = abs(p1.m_y - p2.m_y);
	return xd*xd + yd*yd;
}

// BoardHPoint

BoardHPoint::BoardHPoint()
{
	m_x = 0;
	m_y = 0;
	exists = false;
}

BoardHPoint::BoardHPoint(const BoardHPoint &p)
{
	m_x = p.m_x;
	m_y = p.m_y;
	exists = p.exists;
}

BoardHPoint::BoardHPoint(const BoardPoint &p)
{
	m_x = (p.m_x+50)/100;
	m_y = (p.m_y+50)/100;
	exists = p.exists;
}

BoardHPoint::BoardHPoint(int x, int y)
{
	m_x = x;
	m_y = y;
	exists = true;
}

BoardHPoint::~BoardHPoint()
{
}

void BoardHPoint::operator=(BoardHPoint p)
{
	m_x = p.m_x;
	m_y = p.m_y;
	exists = p.exists;
}

bool BoardHPoint::operator==(BoardHPoint p)
{
	return (m_x == p.m_x && m_y == p.m_y && exists && p.exists);
}

bool BoardHPoint::operator!=(BoardHPoint p)
{
	return (m_x != p.m_x || m_y != p.m_y || !exists || !p.exists);
}

void BoardHPoint::operator+=(BoardHPoint p)
{
	m_x += p.m_x;
}

void BoardHPoint::operator-=(BoardHPoint p)
{
	m_y += p.m_y;
}

BoardHPoint BoardHPoint::operator+(BoardHPoint p)
{
	if(!exists && !p.exists) return BoardHPoint();
	if(exists && !p.exists) return *this;
	//if(!exists && p.exists) return p;
	if(!exists && p.exists) return BoardHPoint();
	return BoardHPoint(m_x + p.m_x, m_y + p.m_y);
}

BoardHPoint BoardHPoint::operator-(BoardHPoint p)
{
	if(!exists && !p.exists) return BoardHPoint();
	if(exists && !p.exists) return *this;
	//if(!exists && p.exists) return BoardHPoint(0,0) - p;
	if(!exists && p.exists) return BoardHPoint();
	return BoardHPoint(m_x - p.m_x, m_y - p.m_y);
}

// BoardSize

BoardSize::BoardSize()
{
	m_w = 0;
	m_h = 0;
}

BoardSize::BoardSize(const BoardSize &p)
{
	m_w = p.m_w;
	m_h = p.m_h;
}

BoardSize::BoardSize(unsigned int w, unsigned int h)
{
	m_w = w;
	m_h = h;
}

BoardSize::~BoardSize()
{
}

void BoardSize::operator=(BoardSize p)
{
	m_w = p.m_w;
	m_h = p.m_h;
}

// BoardRect

BoardRect::BoardRect()
{
	//point_exists = false;
	m_x = 0;
	m_y = 0;
	m_w = 0;
	m_h = 0;
}

BoardRect::BoardRect(const BoardRect &p)
{
	m_x = p.m_x;
	m_y = p.m_y;
	m_w = p.m_w;
	m_h = p.m_h;
	//point_exists = p.point_exists;
}

BoardRect::BoardRect(int x, int y, unsigned int w, unsigned int h)
{
	m_x = x;
	m_y = y;
	m_w = w;
	m_h = h;
	//point_exists = true;
}

BoardRect::~BoardRect()
{
}

void BoardRect::operator=(BoardRect p)
{
	m_w = p.m_w;
	m_h = p.m_h;
	m_x = p.m_x;
	m_y = p.m_y;
	//point_exists = p.point_exists;
}

void BoardRect::SetPoint(BoardPoint p)
{
	//point_exists = p.exists;
	m_x = p.m_x;
	m_y = p.m_y;
}

BoardPoint BoardRect::GetPoint()
{
	//if(!point_exists) BoardPoint();
	return BoardPoint(m_x, m_y);
}

void BoardRect::SetSize(BoardSize s)
{
	m_w = s.m_w;
	m_h = s.m_h;
}

BoardSize BoardRect::GetSize()
{
	return BoardSize(m_w, m_h);
}

bool BoardRect::Collides(BoardRect r)
{
	int x1 = m_x;
	int y1 = m_y;
	int x2 = m_x + m_w;
	int y2 = m_y + m_h;
	int rx1 = r.m_x;
	int ry1 = r.m_y;
	int rx2 = r.m_x + r.m_w;
	int ry2 = r.m_y + r.m_h;

	/*std::cout<<x1<<","<<y1<<","<<x2<<","<<y2<<" - "
			<<rx1<<","<<ry1<<","<<rx2<<","<<ry2<<std::endl;*/

	return (rx2 > x1 && rx1 < x2 && ry2 > y1 && ry1 < y2);
}

bool BoardRect::Contains(BoardRect r)
{
	int x1 = m_x;
	int y1 = m_y;
	int x2 = m_x + m_w;
	int y2 = m_y + m_h;
	int rx1 = r.m_x;
	int ry1 = r.m_y;
	int rx2 = r.m_x + r.m_w;
	int ry2 = r.m_y + r.m_h;

	/*std::cout<<x1<<","<<y1<<","<<x2<<","<<y2<<" - "
			<<rx1<<","<<ry1<<","<<rx2<<","<<ry2<<std::endl;*/

	return (rx1 > x1 && rx2 < x2 && ry1 > y1 && ry2 < y2);
}


